package hk.ces.oxfam.patch.result;

import hk.ces.oxfam.patch.sql.PreparedSQL;
import hk.ces.oxfam.patch.util.StringUtil;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 *
 * @author ReutyCheng
 */
public class BaseSQLResult extends AbstractSQLResult implements SQLResult
{
  private final PreparedSQL preparedSQL;

  public BaseSQLResult(ResultSet resultSet, PreparedSQL preparedSQL) throws SQLException
  {
    super(resultSet);
    this.preparedSQL = preparedSQL;
  }

  public Set<String> getTableNames()
  {
    return tableNames;
  }

  public String[] getColumnNames()
  {
    return columnNames;
  }

  public List<Object[]> getResultsList()
  {
    return resultsList;
  }

  public int getColumnIndex(String columnName, boolean ignoreCase)
  {
    return StringUtil.getIndex(columnName, columnNames, ignoreCase);
  }

  public String getColumnName(int columnIndex)
  {
    if (columnIndex < 0 || columnIndex >= getColumnCount())
    {
      return null;
    }
    else
    {
      return columnNames[columnIndex];
    }
  }

  public Object[] getResultsValue(int resultsIndex)
  {
    if (resultsIndex < 0 || resultsIndex >= getResultsCount())
    {
      return null;
    }
    else
    {
      return resultsList.get(resultsIndex);
    }
  }

  public <T> List<T> getColumnValue(String columnName, boolean ignoreCase, Class<T> clazz)
  {
    int columnIndex = getColumnIndex(columnName, ignoreCase);
    return getColumnValue(columnIndex, clazz);
  }

  public <T> List<T> getColumnValue(int columnIndex, Class<T> clazz)
  {
    if (columnIndex < 0 || columnIndex >= getColumnCount())
    {
      return null;
    }
    else
    {
      List<T> list = new ArrayList<T>(getResultsCount());
      for (Object[] results : resultsList)
      {
        list.add((T) results[columnIndex]);
      }

      return list;
    }
  }

  public <T> T getValue(int resultsIndex, String columnName, boolean ignoreCase, Class<T> clazz)
  {
    int columnIndex = getColumnIndex(columnName, ignoreCase);
    return getValue(resultsIndex, columnIndex, clazz);
  }

  public <T> T getValue(int resultsIndex, int columnIndex, Class<T> clazz)
  {
    if (columnIndex < 0 || columnIndex >= getColumnCount() || resultsIndex < 0 || resultsIndex >= getResultsCount())
    {
      return null;
    }
    else
    {
      return (T) resultsList.get(resultsIndex)[columnIndex];
    }
  }

  public int getTableCount()
  {
    return tableNames.size();
  }

  public int getColumnCount()
  {
    return columnNames.length;
  }

  public int getResultsCount()
  {
    return resultsList.size();
  }

  public boolean isTableExist(String tableName, boolean ignoreCase)
  {
    if (ignoreCase)
    {
      return StringUtil.getIndex(tableName, tableNames, ignoreCase) > -1;
    }
    else
    {
      return tableNames.contains(tableName);
    }
  }

  public boolean isColumnExist(String columnName, boolean ignoreCase)
  {
    return StringUtil.getIndex(columnName, columnNames, ignoreCase) > -1;
  }

  public boolean isResultsRmpty()
  {
    return resultsList.isEmpty();
  }

  public PreparedSQL getPreparedSQL()
  {
    return this.preparedSQL;
  }
}
